﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using ITAP.Core.Modelling.Primitives;
using ITAP.Core.Calculations;
using ITAP.Core.Modelling;

namespace ITAP.ContourBuilder.Components.Dimensions
{
    public enum OffsetFromMainBorderDimensionType
    {
        Undefined,
        Right,
        Up,
        Left,
        Down
    }

    [Serializable]
    public class OffsetFromMainBorderDimension : Dimension
    {
        private double leaderLength = 40;

        public double LeaderLength
        {
            get { return leaderLength; }
            set { leaderLength = value; }
        }

        public ContourContainer Container
        {
            get 
            {
                foreach (IContourComponent component in this.connectedComponents)
                    if (component is ContourContainer)
                        return component as ContourContainer;

                return null;
            }
        }
        private OffsetFromMainBorderDimensionType type = OffsetFromMainBorderDimensionType.Undefined;

        public OffsetFromMainBorderDimensionType Type
        {
            get { return type; }
            set { type = value; }        
        }

        private double offset = 0.5;

        private ModelPoint position;
        public override ModelPoint Position
        {
            get
            {
                return position;
            }
        }

        public override IPrimitive Primitive
        {
            get
            {
                ModelPoint endPoint = null;
                ModelPoint startPoint = this.Position;
                ContourContainer container = this.Container;
                switch(this.type)
                {
                    case OffsetFromMainBorderDimensionType.Right:
                        endPoint = ModelCalculations.GetOffsetPoint(startPoint, new ModelVector(-container.RightIndent, 0));
                        break;
                    case OffsetFromMainBorderDimensionType.Up:
                        endPoint = ModelCalculations.GetOffsetPoint(startPoint, new ModelVector(0, -container.UpIndent));
                        break;
                    case OffsetFromMainBorderDimensionType.Left:
                        endPoint = ModelCalculations.GetOffsetPoint(startPoint, new ModelVector(container.LeftIndent, 0));
                        break;
                    case OffsetFromMainBorderDimensionType.Down:
                        endPoint = ModelCalculations.GetOffsetPoint(startPoint, new ModelVector(0, Container.DownIndent));
                        break;
                }
                return new Line(startPoint, endPoint);
            }
            set
            {
            }
        }

        public override string DimensionText
        {
            get
            {
                string prefix = "";
                if (this.PrefixSymbol != string.Empty)
                    prefix = this.PrefixSymbol + " = ";
                switch (this.type)
                {
                    case OffsetFromMainBorderDimensionType.Right:
                        return prefix + this.Container.RightIndent.ToString("0.0");
                    case OffsetFromMainBorderDimensionType.Up:
                        return prefix + this.Container.UpIndent.ToString("0.0");
                    case OffsetFromMainBorderDimensionType.Left:
                        return prefix + this.Container.LeftIndent.ToString("0.0");
                    case OffsetFromMainBorderDimensionType.Down:
                        return prefix + this.Container.DownIndent.ToString("0.0");
                }
                return prefix;
            }
        }

        public override ITAP.Core.Modelling.ModelVector GetSizeLineNormal()
        {
            return new ModelVector(0, -1);
        }

        public override void AcceptDimensionVisitor(IDimensionVisitor visitor)
        {
            visitor.Visit(this);
        }

        public override bool HasBoundingBox
        {
            get
            {
                return false;
            }
            set
            {
            }
        }

        public override void Recalculate()
        {
            RectangleF bbox = this.Container.BoundingBox;
            switch (this.type)
            {
                case OffsetFromMainBorderDimensionType.Right:
                    position = new ModelPoint(bbox.X + bbox.Width, bbox.Y + bbox.Height * offset);
                    break;
                case OffsetFromMainBorderDimensionType.Up:
                    position = new ModelPoint(bbox.X + (1 - offset) * bbox.Width, bbox.Y + bbox.Height);
                    break;
                case OffsetFromMainBorderDimensionType.Left:
                    position = new ModelPoint(bbox.X, bbox.Y + bbox.Height *(1 - offset));
                    break;
                case OffsetFromMainBorderDimensionType.Down:
                    position = new ModelPoint(bbox.X + offset * bbox.Width, bbox.Y);
                    break;
            }
            this.leaderLength = this.Primitive.Length * 2;
        }

        public override void MoveWithOffset(ModelVector offset)
        {
            switch (this.type)
            {
                case OffsetFromMainBorderDimensionType.Left:
                    this.offset -= offset.Y / this.GetRootContainer().BoundingBox.Height;
                    break;
                case OffsetFromMainBorderDimensionType.Right:
                    this.offset += offset.Y / this.GetRootContainer().BoundingBox.Width;
                    break;
                case OffsetFromMainBorderDimensionType.Down:
                    this.offset += offset.X / this.GetRootContainer().BoundingBox.Width;
                    break;
                case OffsetFromMainBorderDimensionType.Up:
                    this.offset -= offset.X / this.GetRootContainer().BoundingBox.Width;
                    break;
            }

            if (this.offset > 1)
                this.offset = 1;
            if (this.offset < 0)
                this.offset = 0;
        }      
    }
}
